package com.ndkj.blog.service.impl;

import com.alibaba.fastjson.JSON;
import com.ndkj.blog.constant.BlogConstant;
import com.ndkj.blog.constant.FaceConstant;
import com.ndkj.blog.pojo.bo.FaceVerifyBO;
import com.ndkj.blog.pojo.bo.SettingModelBO;
import com.ndkj.blog.utils.GsonUtils;
import com.ndkj.blog.utils.LoginUserCheck;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;

/**
 * @program: Blog
 * @description: 人脸识别 & 活体检测
 * @author: liuyong
 * @create: 2021-09-23 17:24
 */
@Service
@Slf4j(topic = "com.liuyo.top")
public class LoginService {

    @Autowired
    private BaiduAIFace faceApi;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private LoginUserCheck loginUserCheck;
    @Autowired
    private FaceLiveVerify faceLiveVerify;

    public Map<String, Object> searchFace(StringBuffer imagebase64) throws IOException {
        String imgBase64 = imagebase64.substring(imagebase64.indexOf(",") + 1, imagebase64.length());
        System.out.println("get the image:" + imgBase64.substring(0, Math.min(imagebase64.length(), 150)) + "...");
        SettingModelBO settingModelBO = new SettingModelBO();
        settingModelBO.setImgpath(imgBase64);
        settingModelBO.setGroupID("root");
        return faceApi.faceSearch(settingModelBO);
    }

    public String searchFace(StringBuffer imagebase64, Model model, HttpServletRequest request) throws IOException {
        // 人脸检测
        Map<String, Object> faceData = searchFace(imagebase64);
        // 登录失败
        if (faceData == null || faceData.get("user_id") == null) {
            return FaceConstant.FaceCheckReturn.FAIL;
        }
        String user_id = faceData.get("user_id").toString();
        double similarScore = Double.parseDouble("0." + faceData.get("score").toString());
        // 活体检测
        ArrayList<FaceVerifyBO> faceVerifyBOS = new ArrayList<>();
        FaceVerifyBO faceVerifyBO = new FaceVerifyBO();
        faceVerifyBO.setImage_type(FaceConstant.FaceEncoding.ENCODING_TYPE_BASE64);
        String substring = imagebase64.substring(imagebase64.indexOf(",") + 1, imagebase64.length());
        faceVerifyBO.setImage(substring);
        faceVerifyBOS.add(faceVerifyBO);
        String liveResponse = faceLiveVerify.faceVerify(faceVerifyBOS);
        if (StringUtils.isBlank(liveResponse)) {
            return JSON.toJSONString(FaceConstant.FaceCheckReturn.FAIL);
        }
        String liveScoreStr = liveResponse.substring(liveResponse.indexOf("livemapscore") + 14, liveResponse.indexOf("}]") - 1);
        if (StringUtils.isBlank(liveScoreStr)) {
            return JSON.toJSONString(FaceConstant.FaceCheckReturn.FAIL);
        }
        double liveScore = Double.parseDouble(liveScoreStr);
        log.info("人脸相似度得分:{}", similarScore);
        log.info("活体检测相似度得分:{}", liveScore);

        if (similarScore >= FaceConstant.FaceLogin.FACE_SIMILAR_ACCEPT_RATE
                && liveScore >= FaceConstant.FaceLogin.FACE_LIVE_ACCEPT_RATE) {
            model.addAttribute(BlogConstant.AdminConstant.SESSION_KEY, user_id);
            HttpSession session = request.getSession();
            session.setAttribute(BlogConstant.AdminConstant.SESSION_KEY, user_id);
            log.info("人脸识别登录成功");
            log.info("user:{} had been saved to session.", user_id);
            return GsonUtils.toJson(faceData);
        }
        if (faceData.get("score") != null) {
            faceData.put("score", 0);
        }
        log.error("人脸验证登录失败");
        model.addAttribute("msg", "人脸验证失败！");
        return JSON.toJSONString(FaceConstant.FaceCheckReturn.FAIL);
    }

    public String faceLoginSessionCheck(HttpSession session, Model model) {
        if (session.getAttribute(BlogConstant.AdminConstant.SESSION_KEY) != null) {
            String userName = BlogConstant.AdminConstant.DEFAULT_ADMIN_NAME;
            log.info("session验证成功");
            loginUserCheck.adminLoginAttributionCheck();
            return "redirect:/admin/adminIndex?username=" + userName;
        }
        log.error("session认证失败，拦截该登录请求");
        return "redirect:/admin/login";
    }
}
